import * as Cesium from "cesium";
import type { FixedLengthArray } from "@utils";
import CartesianLatLng from "./utils/cartesianLatLng";

export interface DrawRoundType {
  position: FixedLengthArray<number, 2>;
  color: FixedLengthArray<number, 4>;
  radius: number;
  name: string;
  data?: any;
}
export interface DrawRoundUpdateType {
  position: FixedLengthArray<number, 2>;
  color?: FixedLengthArray<number, 4>;
  radius?: number;
  data?: any;
}
// 绘制圆
class DrawRound {
  #viewer: Cesium.Viewer;
  #position: FixedLengthArray<number, 2>;
  #color: FixedLengthArray<number, 4>;
  #radius: number;
  #name: string;
  data: any;
  entity: (Cesium.Entity & { data?: any; _node?: any }) | null;
  constructor(viewer: Cesium.Viewer, options: DrawRoundType) {
    this.#viewer = viewer;
    this.#position = options.position;
    this.#name = options.name;
    this.#color = options.color;
    this.entity = null;
    this.#radius = options.radius;
    this.data = options.data;
    this.#init();
  }
  #init() {
    this.entity = this.#viewer.entities.add({
      name: this.#name,
      position: Cesium.Cartesian3.fromDegrees(...this.#position),
      ellipse: {
        semiMinorAxis: this.#radius, //椭圆短轴（单位米）
        semiMajorAxis: this.#radius, //椭圆长轴（单位米）
        outline: true,
        outlineColor: Cesium.Color.WHITE,
        outlineWidth: 4,
        material: Cesium.Color.fromBytes(
          this.#color[0] * 255,
          this.#color[1] * 255,
          this.#color[2] * 255,
          this.#color[3] * 255
        ),
      },
    });
    this.entity.data = this.data;
    this.entity._node = this;
  }
  click(_e: any, _data?: any) {}
  setShow(show: boolean) {
    this.entity!.show = show;
  }
  update(options: DrawRoundUpdateType) {
    if (options.position) {
      (this.entity as any).position = Cesium.Cartesian3.fromDegrees(
        ...options.position
      );
    }
    if (options.radius) {
      (this.entity as any).ellipse.semiMinorAxis = options.radius;
      (this.entity as any).ellipse.semiMajorAxis = options.radius;
    }
    if (options.color) {
      (this.entity as any).ellipse.material = Cesium.Color.fromBytes(
        options.color[0] * 255,
        options.color[1] * 255,
        options.color[2] * 255,
        options.color[3] * 255
      );
    }
    if (options.data) {
      this.entity!.data = options.data;
    }
  }
  destroy() {
    if (this.entity) {
      this.#viewer.entities.remove(this.entity);
      this.entity = null;
    }
  }
}
// 采集圆
class AcquisitionRound {
  #viewer: Cesium.Viewer;
  #handler: Cesium.ScreenSpaceEventHandler | null;
  #centerPoint: (Cesium.Entity & { data?: any; _node?: any }) | null = null; //中心点
  #ellipseGather: (Cesium.Entity & { data?: any; _node?: any }) | null = null; //采集的圆对象;
  #centerDots: null | { lng: number; lat: number; height: number } = null; //采集的圆对象;
  constructor(viewer: Cesium.Viewer) {
    this.#viewer = viewer;
    this.#handler = new Cesium.ScreenSpaceEventHandler(
      this.#viewer.scene.canvas
    );
    this.#centerPoint = null; //中心点
    this.#ellipseGather = null; //采集的圆对象;
    this.#centerDots = null;
  }
  start() {
    this.#centerPoint = null; //中心点
    this.#ellipseGather = null; //采集的圆对象;
    //进制地图移动
    this.#viewer.scene.screenSpaceCameraController.enableRotate = false;
    this.#viewer.scene.screenSpaceCameraController.enableTranslate = false;
    this.#viewer.scene.screenSpaceCameraController.enableZoom = false;

    this.#handler!.setInputAction((event: any) => {
      //获取加载地形后对应的经纬度和高程：地标坐标
      var ray = this.#viewer.camera.getPickRay(event.position);
      var cartesian = this.#viewer.scene.globe.pick(ray!, this.#viewer.scene);
      if (!Cesium.defined(cartesian)) {
        return;
      }
      let { lng, lat, height } = CartesianLatLng.CartesianToLatLng(cartesian);
      this.#centerDots = { lng, lat, height };
      this.#centerPoint = this.#viewer.entities.add({
        name: "centerPoint",
        position: Cesium.Cartesian3.fromDegrees(lng, lat, height),
        point: {
          color: Cesium.Color.CHARTREUSE.withAlpha(1),
          pixelSize: 10,
          heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
          outlineColor: Cesium.Color.WHITE,
          outlineWidth: 1,
        },
      });
      //默认生成半径为0.1米的圆。
      this.#ellipseGather = this.#viewer.entities.add({
        position: Cesium.Cartesian3.fromDegrees(lng, lat, height),
        ellipse: {
          semiMinorAxis: 0.1, //椭圆短轴（单位米）
          semiMajorAxis: 0.1, //椭圆长轴（单位米）
          material: Cesium.Color.GREENYELLOW.withAlpha(0.5),
          outline: true,
          outlineColor: Cesium.Color.WHITE,
          outlineWidth: 3,
        },
      });
      this.#ellipseGather._node = this;
    }, Cesium.ScreenSpaceEventType.LEFT_DOWN);
    // 对鼠标移动事件的监听
    this.#handler!.setInputAction((event: any) => {
      if (this.#centerPoint == null || this.#ellipseGather == null) {
        return;
      }
      //获取加载地形后对应的经纬度和高程：地标坐标
      var ray = this.#viewer.camera.getPickRay(event.endPosition);
      var radiusCartesian = this.#viewer.scene.globe.pick(
        ray!,
        this.#viewer.scene
      );
      if (!radiusCartesian) {
        return;
      }
      var centerCartesian = (this.#centerPoint as any).position.getValue(
        Cesium.JulianDate.now()
      );
      //计算移动点与中心点的距离（单位米）
      var centerTemp =
        this.#viewer.scene.globe.ellipsoid.cartesianToCartographic(
          centerCartesian
        );
      var radiusTemp =
        this.#viewer.scene.globe.ellipsoid.cartesianToCartographic(
          radiusCartesian
        );
      var geodesic = new Cesium.EllipsoidGeodesic();
      geodesic.setEndPoints(centerTemp, radiusTemp);
      var radius = geodesic.surfaceDistance;
      //console.log("radius",radius);
      //如果半径小于0,则不更新圆信息
      if (radius <= 0) {
        return;
      }
      (this.#ellipseGather as any).ellipse.semiMinorAxis =
        new Cesium.CallbackProperty(function (time, result) {
          return radius;
        }, false);
      (this.#ellipseGather as any).ellipse.semiMajorAxis =
        new Cesium.CallbackProperty(function (time, result) {
          return radius;
        }, false);
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    // 对鼠标抬起事件的监听(结束点采集)
    this.#handler!.setInputAction((event: any) => {
      //开始鼠标操作地图
      this.#viewer.scene.screenSpaceCameraController.enableRotate = true;
      this.#viewer.scene.screenSpaceCameraController.enableTranslate = true;
      this.#viewer.scene.screenSpaceCameraController.enableZoom = true;
      //移除地图鼠标点击事件
      this.#handler!.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN);
      //移除地图鼠标移动事件
      this.#handler!.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
      //移除地图鼠标抬起事件
      this.#handler!.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP);
      var ellipsoid = this.#viewer.scene.globe.ellipsoid;
      var cartographic = ellipsoid.cartesianToCartographic(
        (this.#centerPoint as any).position.getValue(Cesium.JulianDate.now())
      );
      var lat = Cesium.Math.toDegrees(cartographic.latitude);
      var lng = Cesium.Math.toDegrees(cartographic.longitude);
      var height = cartographic.height;
      console.log("圆中心点：经度", lng + ",纬度：" + lat + ",高度：" + height);
      console.log(
        "圆半径：",
        this.#ellipseGather?.ellipse?.semiMinorAxis?.getValue() || 0 + "米"
      );
      //如果圆半径小于0.5米则删除，防止出现默认为0.1米的被采集。该种情况则是用户取消圆采集
      if (
        (this.#ellipseGather as any).ellipse.semiMinorAxis?.getValue() < 0.5
      ) {
        this.#viewer.entities.remove(this.#ellipseGather!);
        this.#ellipseGather = null;
      }
      //清除圆中心点和半径点
      this.#viewer.entities.remove(this.#centerPoint!);
      this.#centerPoint = null;
    }, Cesium.ScreenSpaceEventType.LEFT_UP);
  }
  click(_e: any, _data: any) {}
  getData() {
    return {
      center: this.#centerDots,
      radius: (this.#ellipseGather as any).ellipse.semiMinorAxis.getValue(),
      radiusUnit: "m",
    };
  }
  destroy() {
    if (this.#ellipseGather) {
      this.#viewer.entities.remove(this.#ellipseGather);
      this.#ellipseGather = null;
    }
  }
}
// 辑圆
class EditRound {
  constructor(viewer: Cesium.Viewer) {}
}

export { DrawRound, AcquisitionRound, EditRound };
